
#include "DDSafeDelete.h"
#include "SvrNetRPSession.h"
#include "DYSvrNetMan.h"


 


SvrNetRPSession::SvrNetRPSession(DYSvrNetMan *pSvrNet)
{
	m_pSvrNetMan = pSvrNet;

	m_nPacketListCount = 0;
	m_pPacketNodeList  = NULL;

	m_pLastVKeyPacketNode  = NULL;
	m_pLastV2KeyPacketNode = NULL;
	m_pLastV3KeyPacketNode = NULL;
	m_pWritePacketNode     = NULL;
	m_pNewWriteFrameNode   = NULL;

	m_pRealStream = NULL ;

	next = NULL ;
	prev = NULL ;
	m_bUse  = true;
	m_bInit = false;
}

SvrNetRPSession::~SvrNetRPSession(void)
{
	UnInitialize();
}

//#define dkq_test_20100714

BOOL SvrNetRPSession::UnInitialize()
{
	if( !m_bInit )
	{
		return true;
	}
#ifdef dkq_test_20100714
	m_pSvrNetMan->m_xLog.WriteLog(__FILE__,__LINE__,"11 UnInitialize channel:%d!",m_nSession);
#endif

	RemoveAllItem();

#ifdef dkq_test_20100714
	m_pSvrNetMan->m_xLog.WriteLog(__FILE__,__LINE__,"22 UnInitialize channel:%d!",m_nSession);
#endif

	CloseSession();

#ifdef dkq_test_20100714
	m_pSvrNetMan->m_xLog.WriteLog(__FILE__,__LINE__,"33 UnInitialize channel:%d!",m_nSession);
#endif

	if( m_pRealStream != NULL )
	{
		delete m_pRealStream;
		m_pRealStream = NULL;
	}

	DD_AUTO_LOCK  xLock(&m_xPacketSect);

	m_nPacketListCount = 0;
	m_xSendBlock.Release();

	m_pLastVKeyPacketNode  = NULL;
	m_pLastV2KeyPacketNode = NULL;
	m_pLastV3KeyPacketNode = NULL;
	m_pWritePacketNode     = NULL;
	m_pNewWriteFrameNode   = NULL;

	m_bInit = false;

	return true;
}

BOOL SvrNetRPSession::RemoveAllItem()
{
	DD_AUTO_LOCK  xLock(&m_xItemListSect);

	SvrNetRPItem *pItem = NULL;
	int nCount = (int)m_arItemList.size();
	for(int i=0;i<nCount;i++)
	{
		pItem = m_arItemList[i];

		MySafeDelete(pItem);
	}
	m_arItemList.clear();

	return true;
}

BOOL SvrNetRPSession::Initialize(UINT32 nListCount)
{
	UnInitialize();

	DD_AUTO_LOCK  xLock(&m_xPacketSect);

	m_nPacketListCount = nListCount;

	int nLen = m_nPacketListCount * sizeof(NET_PACKET_NODE);
	if( !m_xSendBlock.Allocate( nLen ) )
	{
		return false;
	}

	NET_PACKET_NODE *pPacketList = (NET_PACKET_NODE*)m_xSendBlock.pBuffer;
	UINT32 nLast = m_nPacketListCount - 1;
	//next
	UINT32 i = 0;
	for(i=0;i<nLast;i++)
	{
		pPacketList[i].pNext     = &pPacketList[i+1];
		pPacketList[i].nPacketID = i;
	}
	pPacketList[nLast].pNext     = &pPacketList[0];
	pPacketList[nLast].nPacketID = nLast;
	//prev
	for(i=1;i<m_nPacketListCount;i++)
	{
		pPacketList[i].pPrev = &pPacketList[i-1];
	}
	pPacketList[0].pPrev = &pPacketList[nLast];

	m_pPacketNodeList  = pPacketList;

	m_pWritePacketNode = pPacketList;
	m_pWritePacketNode->nWriteFlag = 1;

	m_pLastVKeyPacketNode  = NULL;
	m_pLastV2KeyPacketNode = NULL;
	m_pLastV3KeyPacketNode = NULL;

	m_bUse  = true ;
	m_bInit = true ;

	m_nCodeLinkType = TG_NET_LINK_VIDEO;

	return true;
}


BOOL SvrNetRPSession::CheckIsWorking()
{
#ifdef dkq_test_svnnet_Session
	m_xLog.WriteLog(__FILE__,__LINE__,"in CheckIsWorking channel!");
#endif

	DD_AUTO_LOCK xLock(&m_xItemListSect);

	FindAndDelExitItem();

	if( m_arItemList.size() > 0 )
	{
		return true;
	}

#ifdef dkq_test_svnnet_Session
	m_xLog.WriteLog(__FILE__,__LINE__,"in CheckIsWorking channel!");
#endif

	return false;
}

inline BOOL SvrNetRPSession::FindAndDelExitItem()
{
	UINT16 wNeedOpenLink = 0;

	SvrNetRPItem *pItem = NULL;
	int nCount = (int)m_arItemList.size();
	for(int i=nCount-1;i>=0;i--)
	{
		pItem = m_arItemList[i];
		if( NULL == pItem )
		{
			m_arItemList.erase(m_arItemList.begin()+i);
		}
		else if( !pItem->m_bThreadRun )
		{
			MySafeDelete(pItem);
			m_arItemList.erase(m_arItemList.begin()+i);
		}
		else
		{
			wNeedOpenLink |= pItem->GetLinkType();
		}
	}

	return TRUE;
}

BOOL SvrNetRPSession::CloseSession()
{
// 	if( m_xDevInfo.nSessionNum < 0xffff )
// 	{
// 		TG_SVR_RS_INFO xInfo;
// 		xInfo.xDevInfo  = m_xDevInfo;
// 		xInfo.nEnable   = 0;
// 		xInfo.hSession   = this;
// 
// 		m_pSvrNetMan->m_xRealStream.funCallBack( &xInfo,m_pSvrNetMan->m_xRealStream.pContext );
// 	}

	return TRUE;
}


int SvrNetRPSession::OpenSession(TG_CONNECT_INFO *pConnectInfo)
{
	return TG_ERR_SUCCESS;
}

void SvrNetRPSession::ChangeLinkType()
{

}

int SvrNetRPSession::GetItemCount(UINT32 &nCount)
{
	DD_AUTO_LOCK xLock(&m_xItemListSect);

	FindAndDelExitItem();

	nCount = (UINT32)m_arItemList.size();
	
	return TG_ERR_SUCCESS;
}

int SvrNetRPSession::RemoveItem(TGHANDLE hItem)
{
	DD_AUTO_LOCK xLock(&m_xItemListSect);

	SvrNetRPItem *pItem = NULL;
	int nCount = (int)m_arItemList.size();
	for(int i=nCount-1;i>=0;i--)
	{
		pItem = m_arItemList[i]; 
		if( NULL == pItem )
		{
			m_arItemList.erase(m_arItemList.begin()+i);
		}
		else if( hItem == pItem )
		{
#ifdef dkq_test_svnnet_Session
			m_xLog.WriteLog(__FILE__,__LINE__,"RemoveItem channel,pItem:%x",pItem);
#endif

			MySafeDelete(pItem);
			m_arItemList.erase(m_arItemList.begin()+i);
			break;
		}
	}

	return TG_ERR_SUCCESS;
}

int SvrNetRPSession::EnforceKeyFrame(TGHANDLE hItem,SOCKET hSocket,TG_UDP_ADDR *pAddr)
{
	DD_AUTO_LOCK xLock(&m_xItemListSect);

	//return NoticeItemState(hItem,0x10,hSocket,pAddr);
	return 0;
}

int SvrNetRPSession::AddItem(NET_PACKET_HEAD *pRetMsgHead,TG_CONNECT_INFO *pConnectInfo,SOCKET hSocket,TG_UDP_ADDR *pAddr)
{
	if( !m_bInit )
	{
		return TG_ERR_NOINIT;
	}

	DD_AUTO_LOCK xLock(&m_xItemListSect);

	int nRet = TG_ERR_FAILURE;

	try
	{
		SvrNetRPItem *pItem = NULL;
		if( NULL == pAddr )
		{
			pItem = new SvrNetRPTcpItem();
		}
		else 
		{
			//pItem = new SvrNetRPUdpItem();
		}
		if( NULL == pItem )
		{
			return TG_ERR_INITERROR;
		}

		pItem->SetRPSession( this );
		pItem->SetConnectInfo( pConnectInfo );
		

		pItem->SetSocket( hSocket,pAddr );

		nRet = pItem->Initialize(pRetMsgHead);
		if( TG_ERR_SUCCESS != nRet )
		{
			pItem->SetSocket( NULL );

			MySafeDelete(pItem);
			return nRet;
		}

#ifdef dkq_test_svnnet_Session
		m_xLog.WriteLog( __FILE__,__LINE__,"item success!");
#endif

		m_arItemList.push_back(pItem);

		FindAndDelExitItem();

		return TG_ERR_SUCCESS;
	}
	catch(...)
	{
	}

	return TG_ERR_FAILURE;
}


BOOL SvrNetRPSession::ResetAllItem()
{
    DD_AUTO_LOCK xLock(&m_xItemListSect);

	SvrNetRPItem *pItem = NULL;
	int nCount = (int)m_arItemList.size();
	for(int i=nCount-1;i>=0;i--)
	{
		pItem = m_arItemList[i];
		if( NULL != pItem )
		{
			pItem->m_bResetSend = TRUE;
		}
	}

	return TRUE;
}



inline void SvrNetRPSession::AdjustNetState(UINT32 nTimeInterval,UINT16 nFrameNum,UINT8 nNetBWState,UINT8 &nDynNetBWState,SINT32 &nAdjLinkTimes)
{
	UINT8  nNewState = nNetBWState;

	if( nTimeInterval > 10*1000 )
	{
		nNewState = Net_BW_State_Key2;

		nAdjLinkTimes += 10;
	}
	else if( nTimeInterval > 5*1000 )
	{
		nNewState = Net_BW_State_Key;

		nAdjLinkTimes += 5;
	}
	else if( nTimeInterval > 600 )
	{
		nNewState = Net_BW_State_16;

		nAdjLinkTimes += 2;
	}
	else if( nTimeInterval > 320 )
	{
		nNewState = Net_BW_State_8;

		nAdjLinkTimes++;
	}
	else if( nTimeInterval > 160 )
	{
		nNewState = Net_BW_State_4;
	}
	else if( nTimeInterval > 60 )
	{
		nNewState = Net_BW_State_2;
	}
	else
	{
		nNewState = Net_BW_State_1;

		nAdjLinkTimes -= 2;
	}

	if( nNewState > nDynNetBWState )           //down frame rate
	{
		nDynNetBWState = nNewState;
	}
	else if( nNewState >= nNetBWState          //request frame rate
		&& nNewState < nDynNetBWState )      //up frame rate
	{
		if( nDynNetBWState <= Net_BW_State_16 )
		{
			if( 0 == ( nFrameNum%(1<<nNewState) ) )
			{
				nDynNetBWState  = nNewState;
			}
		}
		else if( 0 == nFrameNum )             //wait I frame to up
		{
			nDynNetBWState = nNewState;
		}
	}
}

inline void SvrNetRPSession::AdjustDynamicLinkType(UINT16 nFrameType, READ_PACKET *pReadPacket)
{
	if( pReadPacket->nAdjustLinkTimes > 200 )        //V->V2->V3
	{
		switch( pReadPacket->nDynLinkType & 0x2F )
		{
		case TG_NET_LINK_V: 
			{
				if( m_nCodeLinkType & TG_NET_LINK_V2 )      //�Ƿ���V2
				{
					if( TG_FRAME_TYPE_V2_I == nFrameType )
					{
						pReadPacket->nDynLinkType     = TG_NET_LINK_V2;
						pReadPacket->nAdjustLinkTimes = 0;
					}
				}
				else if( m_nCodeLinkType & TG_NET_LINK_V3 ) //�Ƿ���V3
				{
					if( TG_FRAME_TYPE_V3_I == nFrameType )
					{
						pReadPacket->nDynLinkType     = TG_NET_LINK_V3;
						pReadPacket->nAdjustLinkTimes = 0;
					}
				}
			}
			break;
		case TG_NET_LINK_V2:
			{
				if( m_nCodeLinkType & TG_NET_LINK_V3 ) //�Ƿ���V3
				{
					if( TG_FRAME_TYPE_V3_I == nFrameType )
					{
						pReadPacket->nDynLinkType     = TG_NET_LINK_V3;
						pReadPacket->nAdjustLinkTimes = 0;
					}
				}
			}
			break;
		default:
			break;
		}
	}
	else if( pReadPacket->nAdjustLinkTimes < -300 )  //V3->V2->V1
	{
		if( pReadPacket->nDynLinkType > (pReadPacket->nLinkType&0x2F) ) //����ԭʼ��ȡ��������
		{
			switch( pReadPacket->nDynLinkType & 0x2F )
			{
			case TG_NET_LINK_V3: 
				{
					if( m_nCodeLinkType & TG_NET_LINK_V2 )      //�Ƿ���V2
					{
						if( TG_FRAME_TYPE_V2_I == nFrameType )
						{
							pReadPacket->nDynLinkType     = TG_NET_LINK_V2;
							pReadPacket->nAdjustLinkTimes = 0;
						}
					}
					else if( (m_nCodeLinkType & TG_NET_LINK_V)                   //�Ƿ���V
						&& (TG_NET_LINK_V == (pReadPacket->nLinkType&0x2F) ) )   //ԭʼ��ȡ��������
					{
						if( TG_FRAME_TYPE_V_I == nFrameType )
						{
							pReadPacket->nDynLinkType     = TG_NET_LINK_V;
							pReadPacket->nAdjustLinkTimes = 0;
						}
					}
				}
				break;
			case TG_NET_LINK_V2:
				{
					if( m_nCodeLinkType & TG_NET_LINK_V ) //�Ƿ���V
					{
						if( TG_FRAME_TYPE_V_I == nFrameType )
						{
							pReadPacket->nDynLinkType     = TG_NET_LINK_V;
							pReadPacket->nAdjustLinkTimes = 0;
						}
					}
				}
				break;
			default:
				break;
			}
		}
	}
}

inline BOOL SvrNetRPSession::CheckReadNextFrame(NET_PACKET_NODE **ppOutReadNode,READ_PACKET *pReadPacket)
{
	NET_PACKET_NODE* pReadNode  = *ppOutReadNode;
	NET_PACKET_NODE* pWriteNode = m_pWritePacketNode->pPrev;

	if( pReadNode->nWriteFlag )
	{
		return FALSE;
	}

	// ����ѻ��ӳ�,���������ȼ�
	UINT32 nTimeInterval  = 0; 
	UINT16 nFrameType     = 0;
	UINT16 nDynLinkType   = 0;
	UINT16 nFrameNum      = 0;
	UINT8  nDynNetBWState = 0;
	BOOL   bFindNextFrame = TRUE;

	while( bFindNextFrame && !pReadNode->nWriteFlag )
	{
		if( 0 != pReadNode->xPacket.xPacketHead.nPacketNum )
		{
			pReadNode = pReadNode->pNext;
			continue;
		}

		nTimeInterval  = pWriteNode->nTimeStamp - pReadNode->nTimeStamp; 

		nDynLinkType   = pReadPacket->nDynLinkType;
		nFrameType     = pReadNode->xPacket.xPacketHead.nMsgType;
		nFrameNum      = pReadNode->xPacket.xPacketHead.nFrameNum;
		switch( nFrameType & 0xF0 )
		{
		case TG_FRAME_TYPE_V:
			{

#define DD_CHECK_I_FRAME ( 0x01 == (nFrameType & 0x03) )

				if( DD_CHECK_I_FRAME                                   //I frame
					&& ( 0 == pReadPacket->nMulitVideoRate ) )         //request single video code rate
				{
					AdjustDynamicLinkType( nFrameType,pReadPacket ); 
					nDynLinkType = pReadPacket->nDynLinkType;
				}
				switch( nFrameType & 0x2C )
				{
				case TG_FRAME_TYPE_V:
					{
						if( 0 == ( nDynLinkType & (TG_NET_LINK_V & 0x0F ) ) )    //if request V
						{
							break;
						}
						if( pReadPacket->bWaitIFrame && ( !DD_CHECK_I_FRAME ) )
						{
							break;
						}
						pReadPacket->bWaitIFrame = FALSE;

						AdjustNetState( nTimeInterval,nFrameNum,\
							pReadPacket->nNetBWState,pReadPacket->nDynNetBWState,\
							pReadPacket->nAdjustLinkTimes );

						nDynNetBWState = pReadPacket->nDynNetBWState ;

						if( 0 == ( nFrameNum%(1<<nDynNetBWState) ) )
						{
							pReadPacket->pnNetBWState      = &(pReadPacket->nNetBWState);
							pReadPacket->pnDynNetBWState   = &(pReadPacket->nDynNetBWState);

							bFindNextFrame = FALSE;
						}
					}
					break;
				case TG_FRAME_TYPE_V2:
					{
						if( 0 == ( nDynLinkType & (TG_NET_LINK_V2 & 0x0F ) ) )  //if request V2
						{
							break;
						}

						if( pReadPacket->bWaitV2IFrame && ( !DD_CHECK_I_FRAME ) )
						{
							break;
						}
						pReadPacket->bWaitV2IFrame = FALSE;

						AdjustNetState( nTimeInterval,nFrameNum,\
							pReadPacket->nNetV2BWState,pReadPacket->nDynNetV2BWState,\
							pReadPacket->nAdjustLinkTimes );

						nDynNetBWState = pReadPacket->nDynNetV2BWState ;

						if( 0 == ( nFrameNum%(1<<nDynNetBWState) ) )
						{
							pReadPacket->pnNetBWState      = &(pReadPacket->nNetV2BWState);
							pReadPacket->pnDynNetBWState   = &(pReadPacket->nDynNetV2BWState);

							bFindNextFrame = FALSE;
						}
					}
					break;
				case TG_FRAME_TYPE_V3:
					{
						if( 0 == ( nDynLinkType & (TG_NET_LINK_V3 & 0x0F ) ) )
						{
							break;
						}

						if( pReadPacket->bWaitV3IFrame && ( !DD_CHECK_I_FRAME ) )
						{
							break;
						}
						pReadPacket->bWaitV3IFrame = FALSE;

						AdjustNetState( nTimeInterval,nFrameNum,\
							pReadPacket->nNetV3BWState,pReadPacket->nDynNetV3BWState,\
							pReadPacket->nAdjustLinkTimes );

						nDynNetBWState = pReadPacket->nDynNetV3BWState ;

						if( 0 == ( nFrameNum%(1<<nDynNetBWState) ) )
						{
							pReadPacket->pnNetBWState      = &(pReadPacket->nNetV3BWState);
							pReadPacket->pnDynNetBWState   = &(pReadPacket->nDynNetV3BWState);

							bFindNextFrame = FALSE;
						}
					}
					break;
				default:
					break;
				}
			}
			break;
		case TG_FRAME_TYPE_A:
			{
				if( nTimeInterval > 8 * 1000 )
				{
					break;
				}
				bFindNextFrame = FALSE;
			}
			break;
		default:
			{
				bFindNextFrame = FALSE;
			}
			break;
		}

		if( bFindNextFrame )
		{
			pReadNode = pReadNode->pNext;
		}
	}

	*ppOutReadNode = pReadNode;

	return TRUE;
}


BOOL SvrNetRPSession::ReadPacketData(NET_PACKET_NODE **ppOutReadNode,READ_PACKET *pReadPacket)
{
	if( !m_bInit )
	{
		return FALSE; 
	}

	//printf("33333333333333 ReadPacketData \n");

	NET_PACKET_NODE* pReadNode  = NULL;
	NET_PACKET_NODE* pWriteNode = NULL;

	if( NULL == *ppOutReadNode ) 
	{
		NET_PACKET_NODE *pStartNode = NULL;
		if( pReadPacket->nLinkType & TG_NET_LINK_VIDEO ) //��Ҫ��Ƶ������Ҫ�ȹؼ�֡
		{
			do 
			{
				if( (pReadPacket->nDynLinkType & (TG_NET_LINK_V &0x0F) )  && NULL != m_pLastVKeyPacketNode  )
				{
					pReadPacket->bWaitIFrame  = FALSE;

					pStartNode = m_pLastVKeyPacketNode;
					break;
				}
				if( (pReadPacket->nDynLinkType & (TG_NET_LINK_V2 &0x0F) ) && NULL != m_pLastV2KeyPacketNode )
				{
					pReadPacket->bWaitV2IFrame = FALSE;

					pStartNode = m_pLastV2KeyPacketNode;
					break;
				}
				if( (pReadPacket->nDynLinkType & (TG_NET_LINK_V3 &0x0F) ) && NULL != m_pLastV3KeyPacketNode )
				{
					pReadPacket->bWaitV3IFrame = FALSE;

					pStartNode = m_pLastV3KeyPacketNode;
					break;
				}

				//printf("444444444444444 ReadPacketData  linktype:%x,node:%x,%x,%x \n",pReadPacket->nDynLinkType,m_pLastVKeyPacketNode,m_pLastV2KeyPacketNode,m_pLastV3KeyPacketNode);

				return FALSE;

			} while (FALSE);

			pWriteNode = m_pWritePacketNode->pPrev;

			UINT32 nTimeInterval = pWriteNode->nTimeStamp - pStartNode->nTimeStamp;
			if( nTimeInterval > 3000 ) //ǿ��I֡
			{
				EnforceKeyFrame( pReadPacket->pItem,pReadPacket->pItem->m_hSocket,NULL );
				return FALSE;
			}
		}
		else if( TG_FRAME_TYPE_V != (m_pNewWriteFrameNode->xPacket.xPacketHead.nMsgType&0xF0) )
		{
			pStartNode = m_pNewWriteFrameNode;
		}
		else
		{
			//printf("555555555555 ReadPacketData \n");
			return FALSE;
		}

		*ppOutReadNode = pStartNode;

		pReadNode      = *ppOutReadNode;
	}
	else
	{
		pReadNode  = *ppOutReadNode;
		if( pReadNode->nWriteFlag )
		{
			//printf("66666666666666 ReadPacketData \n");
			return FALSE;
		}

		if( 0 == pReadNode->xPacket.xPacketHead.nPacketNum ) 
		{
			CheckReadNextFrame(ppOutReadNode,pReadPacket);
			pReadNode  = *ppOutReadNode;

#ifdef dkq_test_svnnet_Session
			m_xLog.WriteLog( __FILE__,__LINE__,"nFrameID:%d",pReadNode->xPacket.xPacketHead.nFrameID);
#endif
		}
	}
	if( pReadNode->nWriteFlag )
	{
		//printf("7777777777777 ReadPacketData \n");

		return FALSE;
	}

#ifdef SVR_COPY_SEND_PACKET
	if( NET_PACKET_SIZE == pReadNode->xPacket.xPacketHead.nDataLen )
	{
		*(pReadPacket->pPacket) = pReadNode->xPacket;
	}
	else if( pReadNode->xPacket.xPacketHead.nDataLen > 0  )
	{
		int nLen = pReadNode->xPacket.xPacketHead.nDataLen + sizeof(NET_PACKET_HEAD);
		memcpy(pReadPacket->pPacket,&pReadNode->xPacket,nLen);
		//TGMemCpyMMX(pReadPacket->pPacket,&pReadNode->xPacket,nLen);
	}
#else
	pReadPacket->pPacket = &pReadNode->xPacket;
#endif

	*ppOutReadNode = pReadNode->pNext;


	//printf("44444444444444444 ReadPacketData success \n");

	return TRUE;
}


BOOL SvrNetRPSession::ReadSelectPacketData(UINT16 nFrameID,UINT16 nPacketNum,NET_PACKET_NODE **ppOutReadNode,READ_PACKET *pReadPacket)
{
	if( !m_bInit )
	{
		return false; 
	}

	NET_PACKET_NODE* pReadNode  = NULL;
	NET_PACKET_NODE* pWriteNode = NULL;

#ifdef dkq_test_svnnet_item
	pReadPacket->pItem->m_xLog.WriteLog( __FILE__,__LINE__,"ReadSelectPacketData,nFrameID:%d,nPacketNum:%d ",nFrameID,nPacketNum );
#endif
	
	UINT16 nTimes = 2000;
	if( NULL == *ppOutReadNode ) 
	{
		pReadNode = m_pWritePacketNode->pPrev;
		do 
		{
			pReadNode = pReadNode->pPrev;

		} while ( (--nTimes) && 
			      (!pReadNode->nWriteFlag) &&
				  (pReadNode->xPacket.xPacketHead.nFrameID != nFrameID) &&
				  (pReadNode->xPacket.xPacketHead.nPacketNum != nPacketNum) );

		*ppOutReadNode = pReadNode;
	}
	else
	{
		pReadNode  = *ppOutReadNode;
		while (   (--nTimes) && 
			(!pReadNode->nWriteFlag) &&
			(pReadNode->xPacket.xPacketHead.nFrameID != nFrameID) &&
			(pReadNode->xPacket.xPacketHead.nPacketNum != nPacketNum) )
		{
			pReadNode = pReadNode->pNext;
		}

		*ppOutReadNode = pReadNode;
	}
	if( pReadNode->nWriteFlag || 0 == nTimes )
	{
		return FALSE;
	}


	if( NET_PACKET_SIZE == pReadNode->xPacket.xPacketHead.nDataLen )
	{
#ifdef SVR_COPY_SEND_PACKET
		*(pReadPacket->pPacket) = pReadNode->xPacket;
#else
		pReadPacket->pPacket    = &pReadNode->xPacket;
#endif

		*ppOutReadNode = pReadNode->pNext;

		return TRUE;
	}
	else if( pReadNode->xPacket.xPacketHead.nDataLen > 0  )
	{
#ifdef SVR_COPY_SEND_PACKET
		int nLen = pReadNode->xPacket.xPacketHead.nDataLen + sizeof(NET_PACKET_HEAD);
		memcpy(pReadPacket->pPacket,&pReadNode->xPacket,nLen);
		//TGMemCpyMMX(pReadPacket->pPacket,&pReadNode->xPacket,nLen);
#else
		pReadPacket->pPacket = &pReadNode->xPacket;
#endif
		
		*ppOutReadNode = pReadNode->pNext;

		return TRUE;
	}

	return FALSE;
}


void SvrNetRPSession::SetPacketEvent(void *pFrame,UINT32 nFrameSize)
{
	DD_AUTO_LOCK xLock(&m_xItemListSect);

	SvrNetRPItem *pItem = NULL;
	int nCount = (int)m_arItemList.size();
	for(int i=0;i<nCount;i++)
	{
		pItem = m_arItemList[i];
		if( NULL != pItem  && NULL != pItem->m_pPacketEvent )
		{ 
			sem_post( pItem->m_pPacketEvent );
		}
	}
}




int SvrNetRPSession::SetFrame(void *pFrame,UINT32 nFrameSize)
{
	//printf("pFrame:%x,nFrameSize:%d \n",pFrame,nFrameSize);

	if( NULL == pFrame || nFrameSize <= 0 )
	{
		m_bUse = false ;
		return TG_ERR_PARAMETER_ERROR;
	}

	DD_AUTO_LOCK  xLock(&m_xPacketSect);
	if( !m_bInit )
	{
		return false;
	}

	if( !m_pWritePacketNode->nWriteFlag )
	{
		return false;
	}
	xLock.CancelLock();

	//printf("111111111111111 pFrame:%x,nFrameSize:%d \n",pFrame,nFrameSize);

	TG_FRAME_HEAD *pFrameHead = (TG_FRAME_HEAD *)pFrame;

	//printf("yyyyyyyyyyyyyyyyyy pFrameHead->cFrameType:%x,",pFrameHead->cFrameType);

	UINT16 nFrameType = (UINT16)pFrameHead->cFrameType;
	if( nFrameType & 0x2F )
	{
		m_nCodeLinkType |=  1<<( (nFrameType&0x0C)>>2 );
	}

	UINT16 nFrameID = m_xCreateFlag.CreateFrameID();


	int    nPacketCount    = nFrameSize / NET_PACKET_SIZE;
	UINT32 nLastPacketSize = nFrameSize % NET_PACKET_SIZE;

	if( nLastPacketSize > 0 )
	{
		nPacketCount += 1;
	}

	NET_PACKET_NODE *pWriteNode = m_pWritePacketNode;
	m_pNewWriteFrameNode        = pWriteNode;

	long lOffset  = 0;
	int  nDataLen = 0;

	for(int i=0;i<nPacketCount;i++)
	{
		nDataLen = ( (i<nPacketCount-1)||(0==nLastPacketSize) )?NET_PACKET_SIZE:nLastPacketSize;

		pWriteNode->nWriteFlag = 1;                      // ׼��д
		pWriteNode->nTimeStamp = pFrameHead->nTimeStamp;

		pWriteNode->xPacket.xPacketHead.nFrameID     = nFrameID;
		pWriteNode->xPacket.xPacketHead.nFrameSize   = nFrameSize;
		pWriteNode->xPacket.xPacketHead.nPacketNum   = i;
		pWriteNode->xPacket.xPacketHead.nDataLen     = nDataLen;
		pWriteNode->xPacket.xPacketHead.nMsgType     = (UINT16)pFrameHead->cFrameType;
		pWriteNode->xPacket.xPacketHead.nFrameNum    = pFrameHead->nFrameNum;
		pWriteNode->xPacket.xPacketHead.SetCRC();

		memcpy( pWriteNode->xPacket.cPacketData,(unsigned char*)pFrame+lOffset,nDataLen);
		//TGMemCpyMMX( pWriteNode->xPacket.cPacketData,(unsigned char*)pFrame+lOffset,nDataLen);

		lOffset += nDataLen;

		pWriteNode = pWriteNode->pNext;	
	}


	xLock.ReLock();

	//printf("mmmmmmmmmmmmmmmmmmmmmm pFrameHead->cFrameType:%x,node:%x,%x,%x \n",pFrameHead->cFrameType,m_pLastVKeyPacketNode,m_pLastV2KeyPacketNode,m_pLastV3KeyPacketNode);

	if( TG_FRAME_TYPE_V_I == (pFrameHead->cFrameType&0x23) )
	{
		//printf("kkkkkkkkkkkkk pFrameHead->cFrameType:%x,node:%x,%x,%x \n",pFrameHead->cFrameType,m_pLastVKeyPacketNode,m_pLastV2KeyPacketNode,m_pLastV3KeyPacketNode);

        switch( pFrameHead->cFrameType )
		{
		case TG_FRAME_TYPE_V_I:  m_pLastVKeyPacketNode  = m_pWritePacketNode;break;
		case TG_FRAME_TYPE_V2_I: m_pLastV2KeyPacketNode = m_pWritePacketNode;break;
		case TG_FRAME_TYPE_V3_I: m_pLastV3KeyPacketNode = m_pWritePacketNode;break;
		}
	}

	while( m_pWritePacketNode != pWriteNode)
	{
		m_pWritePacketNode->nWriteFlag = 0;
		m_pWritePacketNode             = m_pWritePacketNode->pNext;
	}
	m_pWritePacketNode->nWriteFlag = 1;

	xLock.CancelLock();

	///////////////

	SetPacketEvent(pFrame,nFrameSize);

	//printf("222222222222222 pFrame:%x,nFrameSize:%d \n",pFrame,nFrameSize);

	return true;
}




int SvrNetRPSession::KeepAlive(NET_SVR_RS_CONTEXT *pContext)
{
// 	DD_AUTO_LOCK xLock(&m_xItemListSect);
// 
// 	SvrNetRPItem *pSvrRsItem = NULL;
// 	UINT32 nCount = (UINT32)m_arItemList.size();
// 
// 	if( pContext->nSvrRsItemPos < nCount &&
// 		m_arItemList[ pContext->nSvrRsItemPos ] == (SvrNetRPItem*)pContext->pSvrRsItem )
// 	{
//         ( (SvrNetRPItem*)pContext->pSvrRsItem )->KeepAlive();
// 
// 		return TG_ERR_SUCCESS;
// 	}
// 	else
// 	{
// 		for(int i=nCount-1;i>=0;i--)
// 		{
// 			pSvrRsItem = m_arItemList[i];
// 			if( NULL != pSvrRsItem && pSvrRsItem == (SvrNetRPItem*)pContext->pSvrRsItem )
// 			{ 
// 				pSvrRsItem->KeepAlive();
// 
// 				return TG_ERR_SUCCESS;
// 			}
// 		}
// 	}

	return TG_ERR_FAILURE;
}

int SvrNetRPSession::SetCmdRetransPacket(NET_SVR_RS_CONTEXT *pContext,NET_PACKET *pPacket)
{
// 	DD_AUTO_LOCK xLock(&m_xItemListSect);
// 
// 	SvrNetRPItem *pItem = NULL;
// 	UINT32 nCount = (UINT32)m_arItemList.size();
// 
// 	if( pContext->nSvrRsItemPos < nCount &&
// 		m_arItemList[ pContext->nSvrRsItemPos ] == (SvrNetRPItem*)pContext->pSvrRsItem )
// 	{
// 		return ( (SvrNetRPItem*)pContext->pSvrRsItem )->SetCmdRetransPacket( pPacket );
// 	}
// 	else
// 	{
// 		for(int i=nCount-1;i>=0;i--)
// 		{
// 			pItem = m_arItemList[i];
// 			if( NULL != pItem && pItem == (SvrNetRPItem*)pContext->pSvrRsItem )
// 			{ 
// 				return pItem->SetCmdRetransPacket( pPacket );
// 			}
// 		}
// 	}

	return TG_ERR_FAILURE;
}
